#pragma once

template<typename T>
struct AutoDeleteBase
{
    T* m_ptr;
    explicit AutoDeleteBase(T* ptr) : m_ptr(ptr){}
    operator bool() const { return !!m_ptr; }
    operator T*() { return m_ptr; }
    operator const T*() const { return m_ptr; }
    T** operator &() { return &m_ptr; }
    T *move() { T* t = m_ptr; m_ptr = nullptr; return t; }
    T* get() { return m_ptr; }
    const T* get() const { return m_ptr; }
};

template<typename T>
struct AutoDelete : public AutoDeleteBase<T>
{
    explicit AutoDelete(T* ptr) : AutoDeleteBase(ptr){}
    ~AutoDelete()
    {
        clear();
    }
    void clear()
    {
        if(!m_ptr) return;
        delete m_ptr;
        m_ptr = nullptr;
    }
};

template<typename T>
struct AutoDeletes : public AutoDeleteBase<T>
{
    explicit AutoDeletes(T* ptr) : AutoDeleteBase(ptr){}
    ~AutoDeletes()
    {
        clear();
    }
    void clear()
    {
        if(!m_ptr) return;
        delete m_ptr;
        m_ptr = nullptr;
    }
};
